package com.lee.rabbitmq.confirm.waitForConfirms;

import com.lee.rabbitmq.util.RabbitMqUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

import java.io.IOException;

/**
 * 普通发送方确认模式
 *
 * @author Lee
 * @createDate 2021/12/16 11:08
 */
public class Send {
    public static void main(String[] args) {
        Connection connection = RabbitMqUtil.getConnection();
        Channel channel = null;
        try {
            channel = connection.createChannel();
            //声明队列
            channel.queueDeclare("confirmQueue",true,false,false,null);


            channel.exchangeDeclare("directConfirmExchange","direct",true);


            channel.queueBind("confirmQueue","directConfirmExchange","confirmRoutingKey");
            String message = "普通发送者确认模式事务测试消息1！";

            //启动发送者确认模式
            channel.confirmSelect();
            channel.basicPublish("directConfirmExchange","confirmRoutingKey",null,message.getBytes("utf-8"));

            /**
             * 阻塞线程等待服务返回响应，用于是否消费发送成功，如果服务确认消费已经发送完成则返回true否则返回false
             * 发送一条确认一次，如果多条确认最后一条
             * 可以为这个方法指定一个毫秒用于确定我们的需要等待服务确认的超时时间，
             * 如果超过了指定的时间以后则会抛出异常InterruptedException表示服务器出现问题了需要补发消息或
             * 将消息缓存到Redis中稍后利用定时任务补发
             * 无论是返回false还是抛出异常消息都有可能发送成功有可能没有发送成功
             * 如果我们要求这个消息一定要发送到队列例如订单数据，那怎么我们可以采用消息补发
             * 所谓补发就是重新发送一次消息，可以使用递归或利用Redis+定时任务来完成补发
             */
            boolean flag = channel.waitForConfirms();
            System.out.println(flag?"消息发送成功!==="+flag:"消息发送失败!==="+flag);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            RabbitMqUtil.close(connection,channel);
        }
    }
}
